home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / mxms_161.arc / CONFIG.C next >
C/C++ Source or Header  |  1991-08-04  |  42KB  |  1,311 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*    Config.c    User configuration routines for Maxmail                   */
  4. /*                                                                          */
  5. /****************************************************************************/
  6.  
  7. #include "MaxMail.h"
  8.  
  9. int _FAR_ _cdecl inp(unsigned);
  10. int _FAR_ _cdecl outp(unsigned, int);
  11.  
  12. int msgnum,handle,areas_sel;
  13. int Usercount;
  14. char msgstr[81];
  15. struct user_cfg uscfg;
  16. struct msgupd_st *msgupd;
  17. struct msgupd_st *prev;
  18.  
  19. #define TIMERMODE 182        /* code to put timer in right mode */
  20. #define FREQSCALE 1190000L    /* basic time frequency in hertz   */
  21. #define TIMESCALE 1230L        /* number of counts in 0.1 second  */
  22. #define T_MODEPORT 67        /* port controls timer mode        */
  23. #define FREQPORT   66        /* port controls tone frequency    */
  24. #define BEEPPORT   97        /* port controls speaker           */
  25. #define ON         79        /* signal to turn speaker on       */
  26.  
  27. void _pascal configmenu(void)
  28. {
  29.    int choice = TRUE;
  30.    char resp;
  31.    int good,x;
  32.    struct packer_st *pack1;
  33.    struct proto_st  *proto1;
  34.  
  35.    do
  36.    {
  37.       clearscreen();
  38.       proto1 = get_curprotolnk();
  39.       pack1 = get_curpacklnk();
  40.       setcolor(TextAttr[STD_TEXT]);
  41.       strout("\r\nMaxMail configuration menu\r\n");
  42.       strout("----------------------------------------------------\r\n");
  43.       setcolor(TextAttr[MENU_KEY]);
  44.       strout("[A]dd message areas\r\n");
  45.       if (USERCFG.totselareas) {
  46.          setcolor(TextAttr[MENU_KEY]);
  47.          strout("[D]elete message areas\r\n");
  48.          strout("[E]rase all current selected message areas\r\n");
  49.       }
  50.       setcolor(TextAttr[MENU_KEY]);
  51.       strout("[H]ang up after download            :");
  52.       setcolor(TextAttr[HILITE_TEXT]);
  53.       if (USERCFG.flags & DLHANGUP)
  54.          strout(" Always, if sysop has it enabled\r\n");
  55.       else strout(" Ask every time\r\n");
  56.       setcolor(TextAttr[MENU_KEY]);
  57.       strout("[L]ist message areas                :");
  58.       setcolor(TextAttr[HILITE_TEXT]);
  59.       if (USERCFG.totselareas)
  60.          sprintf(temp," Currently, %d selected\r\n",USERCFG.totselareas);
  61.       else strcpy(temp," No message areas are currently selected\r\n");
  62.       strout(temp);
  63.       setcolor(TextAttr[MENU_KEY]);
  64.       strout("[M]essage style                     :");
  65.       setcolor(TextAttr[HILITE_TEXT]);
  66.       if (USERCFG.msgfrmt == 1)
  67.          strout(" QWK\r\n");
  68.       else strout(" Standard Text\r\n");
  69.       setcolor(TextAttr[MENU_KEY]);
  70.       strout("[N]ewfiles list included            :");
  71.       setcolor(TextAttr[HILITE_TEXT]);
  72.       if (USERCFG.flags & NEWFILES_INC)
  73.          strout(" Yes\r\n");
  74.       else strout(" No\r\n");
  75.       setcolor(TextAttr[MENU_KEY]);
  76.       strout("[P]acking method                    :");
  77.       setcolor(TextAttr[HILITE_TEXT]);
  78.       if (USERCFG.packer)
  79.          sprintf(temp," %s\r\n",pack1->packname);
  80.       else strcpy(temp," NONE, always ask.\r\n");
  81.       setcolor(TextAttr[HILITE_TEXT]);
  82.       strout(temp);
  83.       if (USERCFG.msgfrmt == 1) {
  84.          setcolor(TextAttr[MENU_KEY]);
  85.          strout("[T]otal messages packed per area    :");
  86.          setcolor(TextAttr[HILITE_TEXT]);
  87.          if (USERCFG.maxareamsgs == 0)
  88.             strout(" ALL\r\n");
  89.          else {
  90.             sprintf(temp," %u\r\n",USERCFG.maxareamsgs);
  91.             strout(temp);
  92.          }
  93.       }
  94.       setcolor(TextAttr[MENU_KEY]);
  95.       strout("[X]fer protocol                     :");
  96.       if (USERCFG.protocol)
  97.          sprintf(temp," %s\r\n",proto1->protoname);
  98.       else strcpy(temp," NONE, always ask.\r\n");
  99.       setcolor(TextAttr[HILITE_TEXT]);
  100.       strout(temp);
  101.       strout("\r\n");
  102.       setcolor(TextAttr[STD_TEXT]);
  103.       strout("[Q]uit to main menu\r\n");
  104.       good = FALSE;
  105.       strout("\r\n");
  106.       while (!good) {
  107.          timeremain();
  108.          setcolor(TextAttr[PROMPT_TEXT]);
  109.          strout("Choice --> ");
  110.          ChatOk = TRUE;
  111.          x = chrin();
  112.          ChatOk = FALSE;
  113.          resp = (char) x;
  114.          if(resp == '\r')
  115.             resp = '0';
  116.          good = TRUE;
  117.          chrout(resp);
  118.          strout("\r\n");
  119.          setcolor(TextAttr[STD_TEXT]);
  120.          switch (toupper((int) resp)) {
  121.             case 'A':        /* add message areas */
  122.                add_msgareas();
  123.                break;
  124.  
  125.             case 'D':        /* delete message areas */
  126.                if (USERCFG.totselareas) 
  127.                   del_msgareas();
  128.                break;
  129.  
  130.             case 'E':        /* Erase all current message areas */
  131.                if (!USERCFG.totselareas)
  132.                   break;
  133.                setcolor(TextAttr[HILITE_TEXT]);
  134.                strout("\r\nAre you sure you wish to erase ALL your currently select message areas?\r\n");
  135.                if (getyn(TRUE)) {
  136.                   memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  137.                   USERCFG.totselareas = 0;
  138.                   msgupd = MSGUPD_1;
  139.                   while (msgupd) {
  140.                      prev = msgupd->next;
  141.                      free(msgupd);
  142.                      msgupd = prev;
  143.                   }
  144.                   MSGUPD_1 = NULL;
  145.                }
  146.                break;
  147.  
  148.             case 'H':        /* Toggle hangup after download */
  149.                USERCFG.flags ^= DLHANGUP;
  150.                break;
  151.  
  152.             case 'L':        /* List msg areas */
  153.                strout("\r\nCurrently selected areas:\r\n\r\n");
  154.                show_areas(FALSE);
  155.                presskey();
  156.                break;
  157.  
  158.             case 'M':        /* Change message format */
  159.                get_msgtype();
  160.                break;
  161.  
  162.             case 'N':        /* Get newfiles type */
  163.                USERCFG.flags ^= NEWFILES_INC;
  164.                break;
  165.  
  166.             case 'P':        /* change packer type */
  167.                get_packer(TRUE);
  168.                break;
  169.  
  170.             case 'Q':
  171.                choice = FALSE;
  172.                break;
  173.  
  174.             case 'T':
  175.                if (USERCFG.msgfrmt == 1) 
  176.                   get_totperarea();
  177.                break;
  178.  
  179.             case 'X':        /* Change download protocol */
  180.                get_proto(TRUE);
  181.                break;
  182.  
  183.             case '!':
  184.             case '0':        /* Redisplay */
  185.                break;
  186.          }
  187.       }
  188.    }
  189.    while (choice);
  190.    USERCFG.flags &= ~USRCFG_UPD;        /* Turn off update flags */
  191.    USERCFG.flags &= ~USRCFG_FUPD;      /* Turn off forced update flags */
  192. }
  193.  
  194. void _pascal getconfig(void)
  195. {
  196.    areas_sel = FALSE;
  197.  
  198.     /* Now ask user to set up message areas to read */
  199.    if (USERCFG.flags & USRCFG_MSGUPD  && !newuser) {
  200.       setcolor(TextAttr[ATTN_TEXT]);
  201.       strout("\r\nSysop has changed available message areas. You are required to redo\r\n");
  202.       strout("your areas selection again,sorry.");
  203.       presskey();
  204.       memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  205.       USERCFG.totselareas = 0;
  206.       msgupd = MSGUPD_1;
  207.       while (msgupd) {
  208.          prev = msgupd->next;
  209.          free(msgupd);
  210.          msgupd = prev;
  211.       }
  212.       MSGUPD_1 = NULL;
  213.       MarkForce();
  214.       add_msgareas();
  215.    }
  216.  
  217.    if (newuser) {
  218.       MarkForce();
  219.       add_msgareas();
  220.       get_msgtype();
  221.       if (USERCFG.msgfrmt == 1) 
  222.          get_totperarea();
  223.       get_packer(TRUE);
  224.       get_proto(TRUE);
  225.    }
  226.    else if (USERCFG.flags & USRCFG_FUPD) {
  227.       setcolor(TextAttr[ATTN_TEXT]);
  228.       strout("\r\nSorry, but the Sysop needs you to re-do your configuration again.");
  229.       presskey();
  230.       memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  231.       USERCFG.totselareas = 0;
  232.       msgupd = MSGUPD_1;
  233.       while (msgupd) {
  234.          prev = msgupd->next;
  235.          free(msgupd);
  236.          msgupd = prev;
  237.       }
  238.       MSGUPD_1 = NULL;
  239.       MarkForce();
  240.       configmenu();
  241.    }
  242. }
  243.  
  244. void _pascal list_config()
  245. {
  246.    struct packer_st *pack1;
  247.    struct proto_st  *proto1;
  248.  
  249.    strout("\r\nYour current MaxMail configuration\r\n");
  250.    strout("-------------------------------------------------------\r\n");
  251.  
  252.    strout("Message areas selected:\r\n");
  253.    show_areas(FALSE);
  254.    proto1 = get_curprotolnk();
  255.    pack1 = get_curpacklnk();
  256.  
  257.    strout("-------------------------------------------------------\r\n");
  258.    if (USERCFG.msgfrmt == 1) 
  259.       strout("Message Format: QWK");
  260.    else strout("Message Format: Standard text");
  261.    if (USERCFG.maxareamsgs) {
  262.       sprintf(temp,"\r\nYou will pack up a maximum of %u messages per area",USERCFG.maxareamsgs);
  263.       strout(temp);
  264.    }
  265.    else strout("\r\nYou will pack up ALL new messages in each area, if possible");
  266.    if (USERCFG.flags & NEWFILES_INC)
  267.       strout("\r\nYou are including a newfiles listing in your mail packet");
  268.    if (USERCFG.protocol)
  269.       sprintf(temp,"\r\nDefault protocol: %s\r\n",proto1->protoname);
  270.    else strcpy(temp,"\r\nDefault protocol: NONE, always ask.\r\n");
  271.    strout(temp);
  272.    if (USERCFG.packer)
  273.       sprintf(temp,"Default packer: %s\r\n",pack1->packname);
  274.    else strcpy(temp,"Default packer: NONE, always ask.\r\n");
  275.    strout(temp);
  276.    if (USERCFG.flags & DLHANGUP) {
  277.       strcpy(temp,"You have turned on automatic Hangup after download\r\n");
  278.       strout(temp);
  279.    }
  280.    strout("-------------------------------------------------------\r\n");
  281.    presskey();
  282. }
  283.  
  284. int _pascal new_user(int filenum)
  285. {
  286.    int x,y;
  287.  
  288.    x = 0;
  289.    USERCFG.flags |= USRCFG_UPD;        /* Force the user to update his configuration */
  290.  
  291. /* Seek to start of file and count records */
  292.    if(lseek(filenum,0L,SEEK_SET) >= 0L)     {    /* Rewind to begginning */
  293.       y = read(filenum,(char *) &uscfg,sizeof(struct user_cfg));
  294.       while (y == sizeof(struct user_cfg)) {
  295.          x++;        /* Simple count */
  296.          y = read(filenum,(char *) &uscfg,sizeof(struct user_cfg));
  297.       }
  298.    }
  299.    return(x);
  300. }
  301.  
  302. void _pascal update_usercfg(int filenum)
  303. {
  304.    lseek(filenum,(long) (UserCfgnum * sizeof(struct user_cfg)),SEEK_SET);        /* Append to tail of file */
  305.    write(filenum,(struct user_cfg *) &USERCFG,sizeof(struct user_cfg));
  306. }
  307.  
  308. /* Convert message number to bitmap location and turn it on */
  309. void _pascal msgmark(int num)
  310. {
  311.    word *bitp;
  312.    int x,mask;
  313.  
  314.    if (isskiparea(num))
  315.       return;
  316.    
  317.    bitp = &USERCFG.msgarea[num / 16];        /* Point to proper slot, 16 bits per slot */
  318.    mask = 1;
  319.    for (x=0; x < (num % 16); x++)
  320.       mask = mask << 1;
  321.    *bitp = *bitp | mask;        /* Turn it on */
  322.    areas_sel = TRUE;
  323.    return;
  324. }
  325.  
  326. /* Convert message number to bitmap location and turn it off */
  327. void _pascal msgunmark(int num)
  328. {
  329.    word *bitp;
  330.    int x,mask;
  331.    
  332.    bitp = &USERCFG.msgarea[num / 16];        /* Point to proper slot, 16 bits per slot */
  333.    mask = 1;
  334.    for (x=0; x < (num % 16); x++)
  335.       mask = mask << 1;
  336.    *bitp &= ~mask;        /* Turn it off */
  337. }
  338.  
  339.  
  340. int _pascal screen_areas(int flag)
  341. {
  342.    int  x,keys,col;
  343.    int  msgpos,anum,index;
  344.    int  areas;
  345.    struct _aidx IDX;
  346.  
  347.    index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  348.    if (index == -1)
  349.       aborterror(FILEOPEN,"Error opening Area index file");
  350.    keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  351.    fseek(afile,IDX.offset,SEEK_SET);
  352.    fread(&AREA,astrlen,1,afile);
  353.    areas = 0;
  354.    anum = 0;
  355.    while (keys) {
  356.       msgpos = 0;
  357.       col = 0;
  358.       while (keys && (msgpos < 20)) {
  359.          keys = testlock();
  360.          if (isskiparea(anum))
  361.             keys = FALSE;         /* If Sysop set skip, don't show this area */
  362.          x = atoi(AREA.name);        /* Get Message area */
  363.          if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys ) {
  364.             if (flag) {        /* If true show areas we don't already have selected */
  365.                if (is_selarea(anum)) {        /* We already have this area */
  366.                   keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  367.                   fseek(afile,IDX.offset,SEEK_SET);
  368.                   fread(&AREA,astrlen,1,afile);
  369.                   anum++;
  370.                   continue;
  371.                }
  372.             }
  373.             areas++;
  374.             if (!col) {     /* 1st column */
  375.                strncpy(temp,AREA.msginfo,20);
  376.                temp[20] = 0;
  377.                sprintf(msgstr,"[%d] %s",anum,temp);
  378.                x = strlen(msgstr);
  379.                while (x++ < 26) 
  380.                   strcat(msgstr," ");        /* Pad it for formatting */
  381.             }
  382.             else {        /* 2nd or 3rd column */
  383.                strncpy(temp1,AREA.msginfo,20);
  384.                temp1[20] = 0;
  385.                sprintf(temp,"[%d] %s",anum,temp1);
  386.                x = strlen(temp);
  387.                while (x++ < 26) 
  388.                   strcat(temp," ");        /* Pad it for formatting */
  389.                strcat(msgstr,temp);
  390.                if (col == 2) {
  391.                   strcat(msgstr,"\r\n");
  392.                   setcolor(TextAttr[STD_TEXT]);
  393.                   strout(msgstr);
  394.                   msgpos++;        /* Another row is spit out */
  395.                   col = -1;
  396.                }
  397.             }
  398.             col++;
  399.          }
  400.          keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  401.          fseek(afile,IDX.offset,SEEK_SET);
  402.          fread(&AREA,astrlen,1,afile);        /* Read next area */
  403.          anum++;
  404.       }
  405.       if (col) {        /* Some message areas left */
  406.          setcolor(TextAttr[STD_TEXT]);
  407.          strcat(msgstr,"\r\n");
  408.          strout(msgstr);
  409.       }
  410.       if (keys) {        /* More areas than a pageful */
  411.          setcolor(TextAttr[PROMPT_TEXT]);
  412.          strout("\r\nMore areas?  ");
  413.          if (getyn(FALSE)) {
  414.             strout("\r\n");
  415.             continue;
  416.          }
  417.          else break;
  418.       }
  419.       else break;
  420.    }
  421.    close(index);
  422.    setcolor(TextAttr[STD_TEXT]);
  423.    return areas;
  424. }
  425.  
  426. void _pascal get_proto(int flag)
  427. {
  428.    byte x;
  429.    char *p;
  430.  
  431.    setcolor(TextAttr[HILITE_TEXT]);
  432.    strout("\r\n\r\nEnter default protocol to use\r\n");
  433.    strout("-----------------------------\r\n");
  434.    setcolor(TextAttr[MENU_KEY]);
  435.    display_protos();
  436.    if (flag)
  437.       strout("[0] Always ask\r\n");
  438.    while (1) {
  439.       timeremain();
  440.       setcolor(TextAttr[PROMPT_TEXT]);
  441.       strout("--> ");
  442.       strin(msgstr);
  443.       if (!IsLocal)
  444.          strout("\r\n");
  445.       p = strtok(msgstr," \r");
  446.       if (!(isdigit(*p)) && p != NULL) {
  447.          setcolor(TextAttr[ATTN_TEXT]);
  448.          strout("You must enter digits only!\r\n");
  449.          continue;
  450.       }
  451.       x = (byte) atoi(p);
  452.       if ((int) x <= totprotocols) {
  453.          if (flag)         /* Allow 0(Always Ask) */
  454.             break;
  455.          if (!flag && x != 0)
  456.             break;
  457.       }
  458.    }
  459.    USERCFG.protocol = x;
  460.  
  461.    USERCFG.totprotos = totprotocols;
  462. }
  463.  
  464. void _pascal get_packer(int flag)
  465. {
  466.    byte x;
  467.    char *p;
  468.  
  469.    x = 0;
  470.    setcolor(TextAttr[HILITE_TEXT]);
  471.    strout("\r\n\r\nEnter packing method you wish to use\r\n");
  472.    strout("------------------------------------\r\n");
  473.    setcolor(TextAttr[MENU_KEY]);
  474.    display_packers();
  475.    if (flag)
  476.       strout("[0] Always ask\r\n");
  477.    while (1) {
  478.       timeremain();
  479.       setcolor(TextAttr[PROMPT_TEXT]);
  480.       strout("--> ");
  481.       strin(msgstr);
  482.       if (!IsLocal)
  483.          strout("\r\n");
  484.       p = strtok(msgstr," \r");
  485.       if (!(isdigit(*p)) && p != NULL) {
  486.          setcolor(TextAttr[ATTN_TEXT]);
  487.          strout("You must enter digits only!\r\n");
  488.          continue;
  489.       }
  490.       x = (byte) atoi(p);
  491.       if ((int) x <= totpackers ) {
  492.          if (flag)         /* Allow 0(Always Ask) */
  493.             break;
  494.          if (!flag && x != 0) 
  495.             break;
  496.       }
  497.    }
  498.  
  499.    if (USERCFG.packer != x && PackDone) {
  500.       PackDone = FALSE;
  501.       erase_arc();
  502.       msgupd = MSGUPD_1;
  503.       while (msgupd) {
  504.          msgupd->update = FALSE;
  505.          msgupd = msgupd->next;
  506.       }
  507.    }
  508.    USERCFG.packer = x;
  509.    USERCFG.totpackers = totpackers;
  510. }
  511.  
  512. int _pascal reset_config(word flag)
  513. {
  514.    int x;
  515.    long pos;
  516.  
  517.    Usercount = 0;
  518.    x = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  519.    if (x == -1) {
  520.       strout("\r\nError opening config file! Try later.\r\n");
  521.       return(FALSE);
  522.    }
  523.    logit("Sysop is reseting all current users",'#');
  524.    lseek(x,0L,SEEK_SET);        /* Rewind to begginning */
  525.    read(x,(char *) &uscfg,sizeof(struct user_cfg));
  526.    while (!eof(x)) {
  527.       pos = tell(x) - (long) sizeof(struct user_cfg);    /* Get position */
  528.       if (uscfg.name[0]) {
  529.          Usercount++;
  530.          uscfg.flags |= flag;
  531.          lseek(x,pos,SEEK_SET);     /* Rewind back to this record */
  532.          write(x,(struct user_cfg *) &uscfg,sizeof(struct user_cfg));
  533.       }
  534.       read(x,(char *) &uscfg,sizeof(struct user_cfg)); /* Next record */
  535.    }
  536.    close(x);
  537.    return(TRUE);
  538. }
  539.  
  540. int _pascal delete_users(void)
  541. {
  542.    int x,User;
  543.    char *p1;
  544.    struct user_cfg USCFG;
  545.  
  546.    if (test_task()) {
  547.       setcolor(TextAttr[ATTN_TEXT]);
  548.       strout("\r\nSorry, but someone else is using MaxMail currently. Try later!\r\n");
  549.    }
  550.    setcolor(TextAttr[STD_TEXT]);
  551.    strout("Enter user's name ---> ");
  552.    strin(temp);
  553.    if (!IsLocal)
  554.       strout("\r\n");
  555.    p1 = strtok(temp,"\t\r\n");
  556.    if (p1) {
  557.       if (strcmpi(p1,LastUser.name) == 0) {
  558.          setcolor(TextAttr[ATTN_TEXT]);
  559.          strout("Whoah there pardner! You can't delete yourself!\r\n");
  560.          return FALSE;
  561.       }
  562.       x = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IWRITE);
  563.       if (x == -1)
  564.          aborterror(FILEOPEN,"Error opening/creating User config file");
  565.       User = find_config(x,p1,&USCFG);
  566.       if (User < 0) {
  567.          setcolor(TextAttr[ATTN_TEXT]);
  568.          strout("Sorry but that user name does not exist.\r\n");
  569.       }
  570.       else {
  571.          strout("User is now being deleted.\r\n");
  572.          sprintf(temp1,"Sysop is deleting user: %s",p1);
  573.          logit(temp1,'#');
  574.          memset(USCFG.name,0,36);        /* Delete */
  575.          lseek(x,(long) User * sizeof(struct user_cfg),SEEK_SET);
  576.          write(x,(struct user_cfg *) &USCFG,sizeof(struct user_cfg));
  577.       }
  578.       close(x);
  579.    }
  580.    return(TRUE);
  581. }
  582.  
  583. void _pascal user_stats(void)
  584. {
  585.    int x,row,handle,y;
  586.    byte z;
  587.    struct tm  *newtime;
  588.    char ttemp[40];
  589.    char *month;
  590.    char *day;
  591.    struct packer_st *packer1;
  592.    struct proto_st *proto1;
  593.  
  594.    setcolor(TextAttr[STD_TEXT]);
  595.    if (!Usercount) {        /* We have to count the active users */
  596.       EmptyRecs = 0;
  597.       handle = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  598.       if (handle == -1) {
  599.          setcolor(TextAttr[ATTN_TEXT]);
  600.          strout("\r\nError opening config file! Try later.\r\n");
  601.          return;
  602.       }
  603.       y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  604.       while (y == sizeof(struct user_cfg)) {
  605.          if (uscfg.name[0])
  606.             Usercount++;
  607.          else{
  608.             EmptyRecs++;
  609.          }
  610.          y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  611.       }
  612.       lseek(handle,0L,SEEK_SET);        /* Rewind file */
  613.    }
  614.    else {
  615.       handle = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  616.       if (handle == -1) {
  617.          strout("\r\nError opening config file! Try later.\r\n");
  618.          return;
  619.       }
  620.    }
  621.    sprintf(temp,"\r\nCurrently, there are %d active users for MaxMail.\r\n",Usercount);
  622.    setcolor(TextAttr[HILITE_TEXT]);
  623.    strout(temp);
  624.    if (EmptyRecs) {
  625.       sprintf(temp,"There are %d empty records in the user file. Use the Pack function to clean.\r\n",EmptyRecs);
  626.       strout(temp);
  627.    }
  628.  
  629. /* Read all the users and display pertinent data */
  630.  
  631.    y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  632.    while (y == sizeof(struct user_cfg)) {
  633.       setcolor(TextAttr[STD_TEXT]);
  634.       strout("__________________________________________________________________________\r\n");
  635.       strout("User Name          Lasttime  Frmt Calls Packs  Packer  Protocol  Flags\r\n");
  636.       strout("--------------------------------------------------------------------------\r\n");
  637.       row = 3;
  638.       setcolor(TextAttr[HILITE_TEXT]);
  639.       while (row < 23 && y == sizeof(struct user_cfg)) {
  640.          while (uscfg.name[0] == 0 && y == sizeof(struct user_cfg)) 
  641.             y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  642.          if (y != sizeof(struct user_cfg)) 
  643.             break;
  644.          strncpy(temp,uscfg.name,15);
  645.          temp[15] = 0;
  646.          while (strlen(temp) < 18)
  647.             strcat(temp," ");
  648.          newtime = localtime(&uscfg.lasttime);
  649.          strcpy(ttemp,asctime(newtime));
  650.          strtok(ttemp," ");               /* Strip Day of week */
  651.          month = strtok(NULL," ");
  652.          day = strtok(NULL," ");
  653.          if (uscfg.calls < uscfg.packcount)
  654.             uscfg.calls = uscfg.packcount;
  655.          if (!uscfg.calls)
  656.             uscfg.calls = 1;
  657.          sprintf(temp1," %s %s    ",month,day);
  658.          strcat(temp,temp1);
  659.          if (uscfg.msgfrmt == 0)
  660.             strcat(temp,"STD");
  661.          else strcat(temp,"QWK");
  662.          sprintf(temp1,"  %5d %5d  ",uscfg.calls,uscfg.packcount);
  663.          strcat(temp,temp1);
  664.          z = USERCFG.packer;
  665.          USERCFG.packer = uscfg.packer;     /* Temporary fix */
  666.          packer1 = get_curpacklnk();
  667.          USERCFG.packer = z;
  668.          if (packer1 == NULL)
  669.             strcat(temp,"None  ");
  670.          else {
  671.             strcpy(temp1,packer1->packname);
  672.             day = strtok(temp1," ");         /* Get 1st name only */
  673.             while (strlen(day) < 6)
  674.                strcat(day," ");
  675.             strcat(temp,day);
  676.          }
  677.          uscfg.packer = (byte) x;
  678.          strcat(temp,"  ");
  679.          z = USERCFG.protocol;
  680.          USERCFG.protocol = uscfg.protocol;     /* Temporary fix */
  681.          proto1 = get_curprotolnk();
  682.          USERCFG.protocol = z;
  683.          if (proto1 == NULL)
  684.             strcat(temp,"None  ");
  685.          else {
  686.             strcpy(temp1,proto1->protoname);
  687.             day = strtok(temp1," ");         /* Get 1st name only */
  688.             strcat(temp,day);
  689.          }
  690.          uscfg.protocol = (byte) x;
  691.          strcat(temp,"    ");
  692.       /* Tack on flags */
  693.          if (uscfg.flags & LASTREAD_UPD)
  694.             strcat(temp,"L");
  695.          if (uscfg.flags & USRCFG_UPD)
  696.             strcat(temp,"U");
  697.          if (uscfg.flags & USRCFG_FUPD)
  698.             strcat(temp,"F");
  699.          if (uscfg.flags & USRCFG_MSGUPD)
  700.             strcat(temp,"M");
  701.          if (uscfg.flags & NEWFILES_INC)
  702.             strcat(temp,"N");
  703.          if (uscfg.flags & DLHANGUP)
  704.             strcat(temp,"H");
  705.          temp[79] = 0;
  706.          strcat(temp,"\r\n");
  707.          strout(temp);
  708.          row++;
  709.          y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  710.       }
  711.       if (y == sizeof(struct user_cfg)) {        /* Still more records */
  712.          strout("\r\nPress ESC to stop or any other key for more");
  713.          x = chrin();
  714.          strout("\r\n");
  715.          if (x == 0x1b) 
  716.             break;
  717.       }
  718.       else break;
  719.    }
  720.    close(handle);
  721.    if (x != 0x1b) {
  722.       presskey();
  723.    }
  724. }
  725.  
  726. void _pascal del_msgareas(void)
  727. {
  728.    char *p;
  729.    int x;
  730.  
  731.    setcolor(TextAttr[STD_TEXT]);
  732.    strout("\r\nYour currently selected message areas\r\n");
  733.    strout("-----------------------------------------\r\n");
  734.    setcolor(TextAttr[HILITE_TEXT]);
  735.    show_areas(FALSE);
  736.    setcolor(TextAttr[STD_TEXT]);
  737.    strout("\r\nEnter message area(s) you wish to delete (Use comma or space to sep)\r\n");
  738.    timeremain();
  739.    setcolor(TextAttr[PROMPT_TEXT]);
  740.    strout("--> ");
  741.    strin(msgstr);
  742.    strout("\r\n");
  743.    p = strtok(msgstr," ,\0");
  744.    while (p) {
  745.       if (isdigit(*p)) {
  746.          msgnum = atoi(p);
  747.          x = is_selarea(msgnum);
  748.          if(x && !(isForcearea(x))) {
  749.             USERCFG.totselareas--;
  750.             msgunmark(msgnum);        /* Delete it */
  751.             x--;
  752.             msgupd = MSGUPD_1;
  753.             if (!x)
  754.                MSGUPD_1 = msgupd->next;
  755.             else {
  756.                while (x) {
  757.                   prev = msgupd;
  758.                   msgupd = msgupd->next;
  759.                   x--;
  760.                }
  761.                prev->next = msgupd->next;        /* Skip current one */
  762.             }
  763.             free(msgupd);
  764.             if (PackDone) {
  765.                logit("User is deleting message areas",'#');
  766.                erase_arc();
  767.                while (msgupd) {
  768.                   msgupd->update = FALSE;
  769.                   msgupd = msgupd->next;
  770.                }
  771.                PackDone = FALSE;
  772.             }
  773.          }
  774.          else if(isForcearea(x)){
  775.             sprintf(temp,"\r\nSorry, but Sysop wants you to pack area #%03d",x);
  776.             setcolor(TextAttr[ATTN_TEXT]);
  777.             strout(temp);
  778.             presskey();
  779.          }
  780.       }
  781.       p = strtok(NULL," ,\0");
  782.    }
  783.    strout("\r\n");
  784. }
  785.  
  786. void _pascal add_msgareas(void)
  787. {
  788.    char *p;
  789.    struct msgupd_st *new;
  790.    int first;
  791.  
  792.    first = TRUE;
  793.    setcolor(TextAttr[HILITE_TEXT]);
  794.    if (USERCFG.totselareas) {
  795.       strout("\r\nYour currently selected message areas\r\n");
  796.       strout("-----------------------------------------\r\n");
  797.       setcolor(TextAttr[MENU_KEY]);
  798.       show_areas(FALSE);
  799.       setcolor(TextAttr[HILITE_TEXT]);
  800.       strout("\r\nOther message areas available\r\n");
  801.    }
  802.    else strout("\r\nMessage areas available\r\n");
  803.    strout("-----------------------------------------\r\n");
  804.    setcolor(TextAttr[MENU_KEY]);
  805.    if(screen_areas(TRUE)) {
  806.       setcolor(TextAttr[HILITE_TEXT]);
  807.       strout("\r\nEnter message area(s) you wish to add (Use comma or space to sep)\r\n");
  808.       timeremain();
  809.       setcolor(TextAttr[PROMPT_TEXT]);
  810.       strout("--> ");
  811.       strin(msgstr);
  812.       strout("\r\n");
  813.       p = strtok(msgstr," ,\0");
  814.       while (p) {
  815.          if (isdigit(*p)) {
  816.             msgnum = atoi(p);
  817.             if(!is_selarea(msgnum)) {
  818.                msgupd = MSGUPD_1;
  819.                if (first) {
  820.                   setcolor(TextAttr[STD_TEXT]);
  821.                   strout("\r\nHang on, I'm scanning the new message areas you selected.....\r\n");
  822.                   first = FALSE;
  823.                }
  824.                new = build1_area(msgnum,TRUE);
  825.                if (new) {
  826.                   if (MSGUPD_1 == NULL) 
  827.                      MSGUPD_1 = new;
  828.                   else {        /* Attach it to the end */
  829.                      prev = msgupd;
  830.                      while (msgupd) {
  831.                         prev = msgupd;
  832.                         msgupd = msgupd->next;
  833.                      }
  834.                      prev->next = new;
  835.                   }
  836.                   msgmark(msgnum);        /* Add it */
  837.                   new->next = NULL;
  838.                   new->update = FALSE;
  839.                   if (PackDone) {
  840.                      logit("User is adding new message areas",'#');
  841.                      erase_arc();
  842.                      msgupd = MSGUPD_1;
  843.                      while (msgupd) {
  844.                         msgupd->update = FALSE;
  845.                         msgupd = msgupd->next;
  846.                      }
  847.                      PackDone = FALSE;
  848.                   }
  849.                }
  850.             }
  851.          }
  852.          p = strtok(NULL," ,\0");
  853.       }
  854.       strout("\r\n");
  855.    }
  856.    else {
  857.       setcolor(TextAttr[ATTN_TEXT]);
  858.       strout("Sorry, you have no other areas you can add at this time.\r\n");
  859.    }
  860.    get_msgcount();        /* Just re-do totselareas */
  861. }
  862.  
  863. void _pascal edit_msgptrs(void)
  864. {
  865.    char *p1;
  866.    char resp;
  867.    int firsttime;
  868.    int good = TRUE;
  869.    int doupdate = FALSE;
  870.    int rows,x;
  871.  
  872.    while (good) {
  873.       firsttime = TRUE;
  874.       msgupd = MSGUPD_1;
  875.       while (msgupd) {
  876.          setcolor(TextAttr[STD_TEXT]);
  877.          strout("\r\n---------------------------------------------------");
  878.          strout("\r\nCurrently selected            Start    High   New  ");
  879.          strout("\r\nMessage Areas                   Msg     Msg   Msgs ");
  880.          strout("\r\n---------------------------------------------------\r\n");
  881.          rows = 0;
  882.          while (msgupd && rows < 17) {
  883.             fseek(afile,msgupd->areaindex,SEEK_SET);
  884.             fread(&AREA,astrlen,1,afile);
  885.             strncpy(temp1,AREA.msginfo,24);
  886.             temp1[24] = 0;
  887.             while (strlen(temp1) < 24)
  888.                strcat(temp1," ");
  889.             sprintf(temp,"[%03d] %s %04d    %04d   %04d\r\n",msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);      
  890.             strout(temp);
  891.             msgupd = msgupd->next;
  892.             rows++;
  893.             firsttime = FALSE;
  894.          }
  895.          if(msgupd) {        /* Still some more, so page it */
  896.             strout("\r\nPress ESC to stop or any other key for more");
  897.             x = chrin();
  898.             strout("\r\n");
  899.             if (x == 0x1b)
  900.                msgupd = NULL;        /* Force a stop */
  901.          }
  902.       }
  903.       if (firsttime) {
  904.          setcolor(TextAttr[ATTN_TEXT]);
  905.          strout("\r\nYou have no currently selected message areas\r\n");
  906.          return;
  907.       }
  908.       else {
  909.          setcolor(TextAttr[STD_TEXT]);
  910.          strout("---------------------------------------------------\r\n");
  911.          setcolor(TextAttr[HILITE_TEXT]);
  912.          strout("\r\nEnter message area # you wish to change ...\r\n");
  913.          strout("Or type 'Q' to exit back to main menu\r\n\r\n");
  914.          timeremain();
  915.          setcolor(TextAttr[PROMPT_TEXT]);
  916.          strout("Message area to change --> ");
  917.          strin(temp);
  918.          if (*temp == '\r')
  919.             break;
  920.          stripwhite(temp);        /* Trim off spaces */
  921.          if (temp) {
  922.             p1 = strtok(temp," \t\r\n");
  923.             if (p1) resp = (char) toupper(*p1);
  924.             else break;        /* No answer, default */
  925.          }
  926.          else break;
  927.          if (resp == 'Q') 
  928.             break;
  929.          else {        /* Parse out message area */
  930.             msgupd = find_area(atoi(p1));
  931.             if (isdigit(resp) && msgupd) {
  932.                setcolor(TextAttr[HILITE_TEXT]);
  933.                strout("\r\n                              Start    High   New  ");
  934.                strout("\r\nMessage Area                    Msg     Msg   Msgs \r\n");
  935.                strout("---------------------------------------------------\r\n");
  936.                fseek(afile,msgupd->areaindex,SEEK_SET);
  937.                fread(&AREA,astrlen,1,afile);
  938.                strncpy(temp1,AREA.msginfo,24);
  939.                temp1[24] = 0;
  940.                while (strlen(temp1) < 24)
  941.                   strcat(temp1," ");
  942.                sprintf(temp,"[%03d] %s %04d    %04d   %04d\r\n",
  943.                   msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);      
  944.                strout(temp);
  945.                strout("\r\n");
  946.                timeremain();
  947.                setcolor(TextAttr[PROMPT_TEXT]);
  948.                strout("Start message # --> ");
  949.                strin(temp);
  950.                if (!IsLocal)
  951.                   strout("\r\n");
  952.                p1 = strtok(temp," \t\r\n");
  953.                if (p1) {
  954.                   firsttime = atoi(p1);
  955.                   if (isdigit(*p1) && (firsttime != (int) msgupd->startmsg)) {
  956.                      firsttime = firsttime >= 1 ? firsttime : 1;
  957.                      firsttime = firsttime <= (int) msgupd->himsg ? firsttime : (int) msgupd->himsg;
  958.                      msgupd->startmsg = firsttime;
  959.                      msgupd->msgcount = msgupd->himsg - msgupd->startmsg;
  960.                      if (msgupd->msgcount < 0)
  961.                         msgupd->msgcount = 0;
  962.                      doupdate = TRUE;
  963.                      msgupd->readmsgs = 0;
  964.                      if (PackDone) {
  965.                         logit("User is resetting message area pointers",'#');
  966.                         PackDone = FALSE;
  967.                         erase_arc();
  968.                      }
  969.                      else if (msg_update)
  970.                         msgupd->update = TRUE;
  971.                   }
  972.                }
  973.             }
  974.          }
  975.       }
  976.    }
  977.    if (doupdate)
  978.       update_msgs();
  979.    setcolor(TextAttr[STD_TEXT]);
  980. }
  981.  
  982. /* Delete users who are no longer active on Maximus user file */
  983.  
  984. void _pascal kill_oldusers(void)
  985. {
  986.    int handl1,handl2;
  987.    int x,y;
  988.    long pos;
  989.  
  990.    if (test_task()) {
  991.       setcolor(TextAttr[ATTN_TEXT]);
  992.       strout("\r\nSorry, but someone else is using MaxMail currently. Try later!\r\n");
  993.    }
  994.  
  995.    handl1 = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYWR,S_IWRITE);
  996.    if (handl1 == -1) {
  997.       setcolor(TextAttr[ATTN_TEXT]);
  998.       strout("\r\nCan't write to user file");
  999.       aborterror(FILEOPEN,"Error opening User config file");
  1000.    }
  1001.  
  1002.    handl2 = sopen(PRM(user_file),O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  1003.    if (handl1 == -1) {
  1004.       setcolor(TextAttr[ATTN_TEXT]);
  1005.       strout("\r\nCan't open User.bbs file\r\n");
  1006.       close(handl1);
  1007.    }
  1008.    y = read(handl1,(char *) &uscfg,sizeof(struct user_cfg));
  1009.    x = 0;
  1010.    while (y == sizeof(struct user_cfg)) {
  1011.       if (uscfg.name[0]) {
  1012.          if (!find_realuser(uscfg.name,handl2)) {
  1013.             memset(uscfg.name,0,36);        /* Null out name */
  1014.             pos = tell(handl1) - (long) sizeof(struct user_cfg);    /* Get position */
  1015.             lseek(handl1,pos,SEEK_SET);     /* Rewind back to this record */
  1016.             write(handl1,(struct user_cfg *) &uscfg,sizeof(struct user_cfg));
  1017.             x++;
  1018.             strout(".");
  1019.          }
  1020.          else strout("*");
  1021.       }
  1022.       else strout("E");
  1023.       y = read(handl1,(char *) &uscfg,sizeof(struct user_cfg));
  1024.    }
  1025.    strout("\r\n");
  1026.    close(handl1);
  1027.    close(handl2);
  1028.    if (x) {
  1029.       setcolor(TextAttr[HILITE_TEXT]);
  1030.       sprintf(temp,"Sysop has deleted %d users from config file",x);
  1031.       strout(temp);
  1032.       strout(".\r\n");
  1033.       logit(temp,'#');
  1034.    }
  1035.    else {
  1036.       setcolor(TextAttr[ATTN_TEXT]);
  1037.       strout("No users are inactive at this time.\r\n");
  1038.    }
  1039.    setcolor(TextAttr[STD_TEXT]);
  1040. }
  1041.  
  1042. /* See if another MaxMail user is currently active */
  1043. int _pascal test_task(void)
  1044. {
  1045.    struct find_t c_file;
  1046.    int x;
  1047.  
  1048.    sprintf(temp,"MxMlAct.%03x",Task);        /* Create a task id */
  1049.    unlink(temp);        /* Delete our own task file */
  1050.  
  1051.    if (_dos_findfirst("MxMlAct.*",_A_NORMAL,&c_file) == 0) { /* Uh oh. Someone else is using MaxMail! */
  1052.       x = sopen(temp,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  1053.       close(x);        /* Re-Create task file */
  1054.       return(TRUE);
  1055.    }
  1056.    x = sopen(temp,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  1057.    close(x);        /* Re-Create task file */
  1058.    return(FALSE);
  1059. }
  1060.  
  1061. void _pascal examine_user(void)
  1062. {
  1063.    int x,y,User,mask,bitloop,areas;
  1064.    int handl1,index;
  1065.    int col,line,anum;
  1066.    char *p1;
  1067.    word *bitp;
  1068.    struct _aidx IDX;
  1069.  
  1070.    setcolor(TextAttr[STD_TEXT]);
  1071.    strout("Enter user's name ---> ");
  1072.    strin(temp);
  1073.    if (!IsLocal)
  1074.       strout("\r\n");
  1075.    p1 = strtok(temp,"\t\r\n");
  1076.    if (p1) {
  1077.       handl1 = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IREAD);
  1078.       if (handl1 == -1)
  1079.          aborterror(FILEOPEN,"Error opening User config file");
  1080.       User = find_config(handl1,p1,&uscfg);
  1081.       if (User < 0) {
  1082.          setcolor(TextAttr[ATTN_TEXT]);
  1083.          strout("Sorry but that user name does not exist.\r\n");
  1084.       }
  1085.       else {        /* Display possible message areas */
  1086.          col = 0;
  1087.          line = 0;
  1088.          areas = 0;
  1089.          index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  1090.          if (index == -1)
  1091.             aborterror(FILEOPEN,"Error opening Area index file");
  1092.          setcolor(TextAttr[STD_TEXT]);
  1093.          for (bitloop=0; bitloop < 64; bitloop++ ) {
  1094.             bitp = &uscfg.msgarea[bitloop];
  1095.             mask = 1;
  1096.             for (x=0; x < 16; x++) {        /* Bitmask loop */
  1097.                if (*bitp & mask) {        /* User selected area */
  1098.                   anum = (bitloop * 16) + x;
  1099.                   lseek(index,(long) (anum * sizeof(struct _aidx)),SEEK_SET);
  1100.                   read(index,(char *)&IDX,sizeof(struct _aidx));
  1101.                   fseek(afile,IDX.offset,SEEK_SET);
  1102.                   y = fread(&AREA,astrlen,1,afile);
  1103.                   if (AREA.msginfo[0]){
  1104.                      areas++;
  1105.                      if (!areas) {        /* First time */
  1106.                         strout("\r\nUser message areas: \r\n");
  1107.                         strout("-------------------\r\n");
  1108.                         rewind(afile);        /* Rewind AREA file */
  1109.                      }
  1110.                      if (!col) {     /* 1st column */
  1111.                         strncpy(temp,AREA.msginfo,20);
  1112.                         temp[20] = 0;
  1113.                         sprintf(msgstr,"[%d] %s",anum,temp);
  1114.                         y = strlen(msgstr);
  1115.                         while (y++ < 26) 
  1116.                            strcat(msgstr," ");        /* Pad it for formatting */
  1117.                      }
  1118.                      else {        /* 2nd or 3rd column */
  1119.                         strncpy(temp1,AREA.msginfo,20);
  1120.                         temp1[20] = 0;
  1121.                         sprintf(temp,"[%d] %s",anum,temp1);
  1122.                         y = strlen(temp);
  1123.                         while (y++ < 26) 
  1124.                            strcat(temp," ");        /* Pad it for formatting */
  1125.                         strcat(msgstr,temp);
  1126.                         if (col == 2) {
  1127.                            strcat(msgstr,"\r\n");
  1128.                            strout(msgstr);
  1129.                            line++;        /* Another row is spit out */
  1130.                            if (line > 23) {
  1131.                               presskey();
  1132.                               line = 0;
  1133.                            }
  1134.                            col = -1;
  1135.                         }
  1136.                      }
  1137.                      col++;
  1138.                   }
  1139.                }
  1140.                mask = mask << 1;
  1141.             }
  1142.          }
  1143.          if (col) {
  1144.             strcat(msgstr,"\r\n");
  1145.             strout(msgstr);
  1146.          }
  1147.          close(index);
  1148.          if (areas) {
  1149.             sprintf(temp,"\r\nTotal areas selected: %d \r\n",areas);
  1150.             strout(temp);
  1151.          }
  1152.       }
  1153.       close(handl1);
  1154.    }
  1155. }
  1156.  
  1157.  
  1158. /* Generate a tone of given frequency and length, time is in 10ths of seconds */
  1159. void _pascal tone (int freq, int time)
  1160. {
  1161.  
  1162.    int  hibyte, lowbyte, port;
  1163.    long divisor;
  1164.  
  1165.    divisor = FREQSCALE / freq;    /* scale freq to timer units  */
  1166.    lowbyte = (int) (divisor % 256); /* break integer into         */
  1167.    hibyte  = (int) (divisor >> 8);        /*  two bytes                 */
  1168.  
  1169.    outp (T_MODEPORT, TIMERMODE);    /* prepare timer for input    */
  1170.    outp (FREQPORT, lowbyte);    /* set low byte of timer reg  */
  1171.    outp (FREQPORT, hibyte); /* set high byte of timer reg */
  1172.  
  1173.    port = inp(BEEPPORT);        /* save port setting          */
  1174.    outp (BEEPPORT, ON);        /* turn speaker on            */
  1175.    delay_ms(time);
  1176.    outp (BEEPPORT, port);        /* turn speaker off, restore  */
  1177.                 /*  original setting          */
  1178. }
  1179.  
  1180.  
  1181. void _pascal get_msgtype(void)
  1182. {
  1183.    int x;
  1184.    unsigned oldfrmt;
  1185.  
  1186.    do
  1187.    {
  1188.       setcolor(TextAttr[HILITE_TEXT]);
  1189.       strout("Enter message format you wish to use\r\n");
  1190.       strout("------------------------------------\r\n");
  1191.       strout("[0]Standard Text      [1]QWK packets\r\n");
  1192.       timeremain();
  1193.       setcolor(TextAttr[PROMPT_TEXT]);
  1194.       strout("--> ");
  1195.       x = chrin();
  1196.       if (x == '\r')
  1197.          x = '0';
  1198.       else if (!(isdigit(x))) {
  1199.          setcolor(TextAttr[ATTN_TEXT]);
  1200.          strout("\r\nYou must enter digits only!\r\n");
  1201.          continue;
  1202.       }
  1203.       setcolor(TextAttr[STD_TEXT]);
  1204.       sprintf(temp,"%c\r\n",x);
  1205.       strout(temp);
  1206.    }
  1207.    while (x != '1' && x != '0' );
  1208.    oldfrmt = USERCFG.msgfrmt;
  1209.    USERCFG.msgfrmt = x - 0x30;
  1210.    if (USERCFG.msgfrmt == 1)
  1211.       qwkinit();
  1212.  
  1213.    if (oldfrmt != USERCFG.msgfrmt && PackDone)
  1214.       erase_arc();
  1215. }
  1216.  
  1217. void _pascal get_nfiles(void)
  1218. {
  1219.    int x;
  1220.  
  1221.    setcolor(TextAttr[HILITE_TEXT]);
  1222.    strout("\r\nDo you wish to include a newfiles list\r\n");
  1223.    strout("  in your packet?\r\n");
  1224.    if (getyn(TRUE))
  1225.       USERCFG.flags |= NEWFILES_INC;
  1226.    else {
  1227.       x = NEWFILES_INC ^ 0xffff;
  1228.       USERCFG.flags &= x;        /* Turn it off */
  1229.    }
  1230. }
  1231.  
  1232. void _pascal get_totperarea(void)
  1233. {
  1234.  
  1235.    if(USERCFG.msgfrmt == 1) {        /* This is only needed for QWK */
  1236.       while (1) {
  1237.          setcolor(TextAttr[HILITE_TEXT]);
  1238.          strout("\r\nEnter maximum # of messages you want to pack in each area\r\n");
  1239.          timeremain();
  1240.          setcolor(TextAttr[PROMPT_TEXT]);
  1241.          strout(" or enter a '0' for full pack per area --> ");
  1242.          strin(msgstr);
  1243.          if (!IsLocal)
  1244.             strout("\r\n");
  1245.          setcolor(TextAttr[STD_TEXT]);
  1246.          stripwhite(msgstr);
  1247.          if (!(isdigit(msgstr[0])) && msgstr[0]) {
  1248.             setcolor(TextAttr[ATTN_TEXT]);
  1249.             strout("You must enter digits only!\r\n");
  1250.             continue;
  1251.          }
  1252.          switch (msgstr[0]) {
  1253.             case 0:
  1254.                USERCFG.maxareamsgs = 0;
  1255.                break;
  1256.  
  1257.             default:
  1258.                if (isdigit(msgstr[0]))
  1259.                   USERCFG.maxareamsgs = (word) (atoi(msgstr));
  1260.                else USERCFG.maxareamsgs = 0;
  1261.          }
  1262.          break;
  1263.       }
  1264.    }
  1265. }
  1266.  
  1267. /* Get a yes/no anser from user. Return TRUE for yes,FALSE for no.
  1268.    If flag is true add timeremain key */
  1269.  
  1270. int _pascal getyn(int flag)
  1271. {
  1272.    int x;
  1273.  
  1274.    if (flag) 
  1275.       timeremain();
  1276.    setcolor(TextAttr[PROMPT_TEXT]);
  1277.    strout("[y,N] ");
  1278.    x = chrin();
  1279.    chrout((char) x);
  1280.    strout("\r\n");
  1281.    if (toupper(x) == 'Y')
  1282.       return TRUE;
  1283.    else return FALSE;
  1284. }
  1285.  
  1286.  
  1287. void _pascal presskey(void)
  1288. {
  1289.    strout("\r\nPress any key");
  1290.    chrin();
  1291.    strout("\r\n");
  1292. }
  1293.  
  1294. /* Test a message area for locks/keys */
  1295.  
  1296. int _pascal testlock(void)
  1297. {
  1298.    int result;
  1299.    unsigned x,y;
  1300.  
  1301.    result = TRUE;        /* Assume yes */
  1302.    if (AREA.msglock) {
  1303.       y = AREA.msglock;
  1304.       x = LastUser.key;
  1305.       if ((x & y) != y)
  1306.          result = FALSE;
  1307.    }
  1308.    return result;
  1309. }
  1310.  
  1311.